package com.ruoyi.yanjing.client;

import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.yanjing.common.DateUtil;
import com.ruoyi.yanjing.config.MqttConfig;
import com.ruoyi.yanjing.domain.DeviceTemperature;
import com.ruoyi.yanjing.domain.MonitorPoint;
import com.ruoyi.yanjing.domain.SendDataLog;
import com.ruoyi.yanjing.domain.mqtt.MqttReceiveData;
import com.ruoyi.yanjing.service.IDeviceTemperatureService;
import com.ruoyi.yanjing.service.IMonitorPointService;
import com.ruoyi.yanjing.service.ISendDataLogService;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author 14820
 */
@Component
public class PushCallback implements MqttCallback {
    private static final Logger logger = LoggerFactory.getLogger(PushCallback.class);

    @Resource
    IDeviceTemperatureService iDeviceTemperatureService;

    @Resource
    IMonitorPointService iMonitorPointService;

    @Resource
    ISendDataLogService sendDataLogService;

    @Autowired
    private MqttConfig mqttConfig;

    @Autowired
    private static MqttClient client;

    private String topic;
    private int qos;
    private String message;

    @Override
    public void connectionLost(Throwable throwable) {
        logger.info("连接断开，可以做重连");
        if (client == null || !client.isConnected()) {
            mqttConfig.addTopicSubscriptionForLoseConnected();
        }
    }

    @Override
    public void messageArrived(String topic, MqttMessage mqttMessage) {
        SendDataLog sendDataLog = new SendDataLog();
        logger.info("接收消息主题 : {}", topic);
        logger.info("接收消息Qos : {}", mqttMessage.getQos());
        logger.info("接收消息内容 : {}", new String(mqttMessage.getPayload()));

        this.topic = topic;
        this.qos = mqttMessage.getQos();
        this.message = new String(mqttMessage.getPayload());


        if(StringUtils.isNotBlank(topic) && topic.contains("query_reply")){
            logger.info("=================网关回复查询："+topic+"=================");
            logger.info("网关回复查询内容 : {}", new String(mqttMessage.getPayload()));

            sendDataLog.setSendSystem("monitor");
            sendDataLog.setServerNo(topic);
            sendDataLog.setServerType("网关回复查询-接收");
            sendDataLog.setCreateTime(new Date());
            sendDataLog.setServerTime(DateUtil.formatDate(new Date(),"yyyy-MM-dd HH:mm:ss"));
            sendDataLog.setSendTime(DateUtil.formatDate(new Date(),"yyyy-MM-dd HH:mm:ss"));
            sendDataLog.setSendParamsType("tcp");

            sendDataLog.setContent(this.message);
            sendDataLog.setSendStatus("接收成功");
            sendDataLogService.insertSendDataLog(sendDataLog);
            return;
        }

        if(StringUtils.isNotBlank(topic) && topic.contains("configure_reply")){
            logger.info("=================网关回复配置："+topic+"=================");
            logger.info("网关回复配置内容 : {}", new String(mqttMessage.getPayload()));
            sendDataLog.setSendSystem("monitor");
            sendDataLog.setServerNo(topic);
            sendDataLog.setServerType("网关回复配置-接收");
            sendDataLog.setCreateTime(new Date());
            sendDataLog.setServerTime(DateUtil.formatDate(new Date(),"yyyy-MM-dd HH:mm:ss"));
            sendDataLog.setSendTime(DateUtil.formatDate(new Date(),"yyyy-MM-dd HH:mm:ss"));
            sendDataLog.setSendParamsType("tcp");

            sendDataLog.setContent(this.message);
            sendDataLog.setSendStatus("接收成功");
            sendDataLogService.insertSendDataLog(sendDataLog);
            return;
        }


        try {
            logger.info("=================开始转换网关数据=================");
            ObjectMapper objectMapper = new ObjectMapper();
            MqttReceiveData data = objectMapper.readValue(this.message, MqttReceiveData.class);
            if(data != null && data.getSensors() != null && data.getSensors().size()>0){
                Date reportTime = new Date();
                if(data.getTimestamp() != null){
//                    // 将 Date 转换为 Instant，减去 8 小时
//                    Instant instant = data.getTimestamp().toInstant().minus(Duration.ofHours(8));

                    // 将调整后的 Instant 转回 Date
                    reportTime = data.getTimestamp();
                }
                List<DeviceTemperature> deviceTemperatureList = new ArrayList<>();
                for (MqttReceiveData.SensorData sensorData : data.getSensors()) {
                    DeviceTemperature deviceTemperature = new DeviceTemperature();

                    MonitorPoint monitorPoint = new MonitorPoint();
                    monitorPoint.setPointCode(sensorData.getSensorId());
                    monitorPoint.setGatewayId(data.getGatewayId());
                    List<MonitorPoint> monitorPoints = iMonitorPointService.selecAllMonitorPointAndLinePoleInfoList(monitorPoint);
                    if(monitorPoints != null && monitorPoints.size()>0){
                        MonitorPoint monitorPoint1 = monitorPoints.get(0);
                        deviceTemperature.setPointId(Long.valueOf(monitorPoint1.getId()));
                        deviceTemperature.setCurrentTemperature(sensorData.getTemperature());

                        deviceTemperature.setReportTime(reportTime);
                        deviceTemperature.setStandby1(sensorData.getOnlineFlag()); //在线状态 1表示在线
                        deviceTemperature.setStandby2(sensorData.getOverTempCfg());//报警温度配置
                        // 使用 ZonedDateTime 获取当前时间，并格式化为 ISO 8601 带 Z
//                        ZonedDateTime now = ZonedDateTime.now(TimeZone.getTimeZone("UTC").toZoneId());

                        if(sensorData.getLastChangeTime() != null){
                            String formattedTime =  DateUtil.formatDate(sensorData.getLastChangeTime(),"yyyy-MM-dd HH:mm:ss");
                            deviceTemperature.setStandb3(formattedTime);//温度最后改变时间
                        }

                        deviceTemperature.setBateryVol(data.getBateryVol());
                        deviceTemperature.setPowerStat(data.getPowerStat());
                        deviceTemperature.setCurrentVoltage(data.getBateryVol());
                        deviceTemperatureList.add(deviceTemperature);
                    }
                }
                if(deviceTemperatureList != null && deviceTemperatureList.size() >0){
                    iDeviceTemperatureService.insertBatch(deviceTemperatureList);
                    logger.info("=================转换网关数据成功=================");
                }else {
                    logger.info("=================转换网关数据失败，无对应网关设备编码以及点位编码=================");
                }

            }

            sendDataLog.setSendSystem("monitor");
            sendDataLog.setServerNo(topic);
            sendDataLog.setServerType("网关主动上报-接收");
            sendDataLog.setCreateTime(new Date());
            sendDataLog.setServerTime(DateUtil.formatDate(new Date(),"yyyy-MM-dd HH:mm:ss"));
            sendDataLog.setSendTime(DateUtil.formatDate(new Date(),"yyyy-MM-dd HH:mm:ss"));
            sendDataLog.setSendParamsType("tcp");

            sendDataLog.setContent(this.message);
            sendDataLog.setSendStatus("接收成功");
            sendDataLogService.insertSendDataLog(sendDataLog);

        } catch (Exception e) {
            logger.info("=================转换网关数据失败=================");
            sendDataLog.setSendSystem("monitor");
            sendDataLog.setServerNo(topic);
            sendDataLog.setServerType("网关主动上报-接收");
            sendDataLog.setCreateTime(new Date());
            sendDataLog.setServerTime(DateUtil.formatDate(new Date(),"yyyy-MM-dd HH:mm:ss"));
            sendDataLog.setSendTime(DateUtil.formatDate(new Date(),"yyyy-MM-dd HH:mm:ss"));
            sendDataLog.setSendParamsType("tcp");

            sendDataLog.setContent(this.message);
            sendDataLog.setSendStatus("接收失败");
            sendDataLogService.insertSendDataLog(sendDataLog);
            e.printStackTrace();
        }

    }

    @Override
    public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
        logger.info("deliveryComplete---------" + iMqttDeliveryToken.isComplete());
    }

    public String receive() {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("topic", topic);
        jsonObject.put("qos", qos);
        jsonObject.put("msg", message);
        return jsonObject.toString();
    }
}
